#include <iostream>
#include <vector>
using namespace std;

//介绍滑动窗口，使用双指针
//1.典型的滑动窗口
//给出数组和一数字target，求该数组内长度最小的和大于或等于target的子数组长度
//前后指针，求指针之间（包括指针）的子数组和，
//若和小，快指针向前（窗口变大）。若大或等于，慢指针向前（窗口变小），并记录最小长度
int minSubArrayLen(int target,vector<int>& nums)
{
    int i=0;
    int result=INT32_MAX;
    int sum=0;
    for(int j=0;j<nums.size();j++)
    {
        sum+=nums[j];
        while(sum>=target)
            {
                result=result>(j-i+1)? j-i+1:result;
                sum-=nums[i++];
            }
    }
    return result==INT32_MAX? 0:result;
    //找不到该数组，返回0
}

//2.每种字符至少取k个：只能从字符串的左或右边取字符，求取到每种字符至少k个的最少次数
//使用一个中间空心的滑动窗口
//先从一边（右）开始一直取直到取完全部k（取不到就返回-1），      记录长度
//然后从另一边取，并削减掉开始一边取的直到有一种字符刚好剩下k个，记录最小长度
//左边进一位，右边也要进一位
int takeKCharacters(string s,int k)
{
    int cnt[3]{};
    int n=s.size(),j=n;
    while((cnt[0]<k||cnt[1]<k||cnt[2]<k)&&j)
        cnt[s[--j]-'a']++;
    if(cnt[0]<k||cnt[1]<k||cnt[2]<k)    
        return -1;
    int ans=n-j;//j减了几次，长度就是几

    //实现滑动：i每次进一位，当j可以后退时一直后退直到不能后退
    //每次记录最小值，就可以相当于使用滑动窗口遍历多种情况
    for(int i=0;i<n;i++)
    {
        cnt[s[i]-'a']++;
        while(j<n&&cnt[s[j]-'a']>k) cnt[s[j++]-'a']--;  //减的时候需要检测是否至少大于k
        ans=min(ans,n-j+i+1);
    }


    return ans;

}